package com.flying.invest.discovery.sample;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;

import com.flying.common.util.Codes;
import com.flying.common.util.DateUtils;
import com.flying.common.util.DateUtils.Field;
import com.flying.framework.annotation.Param;
import com.flying.framework.annotation.Service;
import com.flying.framework.model.ActionResult;
import com.flying.framework.model.ModelFactory;
import com.flying.framework.service.AbstractService;
import com.flying.invest.assets.model.Assets;
import com.flying.invest.assets.model.AssetsPrice;
import com.flying.invest.assets.service.AssetsPriceService;
import com.flying.invest.assets.service.AssetsService;
import com.flying.invest.discovery.model.Discovery;
import com.flying.invest.discovery.model.DiscoveryOpportunity;
import com.flying.invest.discovery.service.DiscoveryOpportunityService;
import com.flying.invest.discovery.service.DiscoveryService;
import com.flying.invest.invest.TransactionType;

@Service("DiscoverySampleService")
public class DiscoverySampleService extends AbstractService {
	private final static NumberFormat nf = new DecimalFormat("0.00");
	private AssetsService as;
	private AssetsPriceService aps;
	private DiscoveryService ds;
	private DiscoveryOpportunityService os;
	
	public void setAssetsService(AssetsService s) {
		this.as = s;
	}
	
	public void setAssetsPriceService(AssetsPriceService s) {
		this.aps = s;
	}
	
	public void setDiscoveryService(DiscoveryService s) {
		this.ds = s;
	}
	
	public void setDiscoveryOpportunityService(DiscoveryOpportunityService s) {
		this.os = s;
	}
	
	public ActionResult run(
			@Param(value=Discovery.DISCOVERY_ID, required=true,	desc="发现ID") Long discovery_id) {
		var discovery = this.ds.findById(discovery_id);
		var assets = this.as.findFavorites(discovery.getUserId(), discovery.getAssetsTypeId(), null, null, null, null, null, null, null, null, null, 
				0, Integer.MAX_VALUE, null, null).getRows();
		assets.stream().forEach(asset -> {
			var result = this.check(asset.getAssetsId());
			if(result.getInteger(Codes.CODE).equals(Codes.SUCCESS)) {
				AssetsPrice max = result.get("max");
				AssetsPrice min = result.get("min");
				AssetsPrice cur = result.get("cur");
				var remarks = asset.getName() + "，"
						+ "最高价格："+max.getPrice()+"("+max.getPriceDate()+")，"
						+ "最低价格："+min.getPrice()+"("+min.getPriceDate()+")，"
						+ "跌幅："+nf.format((max.getPrice() - min.getPrice()) / max.getPrice() * 100) + "%，"
						+ "当前价格："+cur.getPrice()+"("+cur.getPriceDate()+")，"
						+ "回升："+nf.format((cur.getPrice() - min.getPrice()) / min.getPrice() * 100) + "%";
				this.os.create(discovery.getUserId(), discovery_id, asset.getAssetsId(), null, null, 
						asset.getName(), remarks, DiscoveryOpportunity.Status.PREPARING.value, cur.getPrice(), TransactionType.BUY.value, 
						"System", new Date());
			}
		});
		return ModelFactory.create(ActionResult.class, Codes.CODE, Codes.SUCCESS);
	}
	
	public ActionResult check(
			@Param(value=Assets.ASSETS_ID, required=true,	desc="ASSETS ID") Long assets_id) {
		var prices = this.aps.findAllASC(assets_id, new String[] {DateUtils.formatDate(DateUtils.add(new Date(), Field.MONTH, -3),"yyyy-MM-dd"), 
				DateUtils.formatDate(new Date(),"yyyy-MM-dd")}, 0, Integer.MAX_VALUE).getRows();
		try {
			var max = prices.stream().max((x, y) -> x.getPrice().compareTo(y.getPrice())).get();
			var min = prices.stream().filter(x -> x.getPriceDate().compareTo(max.getPriceDate()) >= 0).min((x, y) -> x.getPrice().doubleValue() > y.getPrice().doubleValue()?1:-1).get();
			var cur = prices.get(prices.size() - 1);
			if((max.getPrice() - min.getPrice()) / max.getPrice() > 0.18 && (cur.getPrice() - min.getPrice()) / min.getPrice() > 0.06 ) {
				return ModelFactory.create(ActionResult.class, Codes.CODE, Codes.SUCCESS, 
						"max", max, "min", min, "cur", cur);
			}
		}catch (Exception e) {
			System.err.println("assets ("+assets_id+") check error, reason is:" + e);
		}
		return ModelFactory.create(ActionResult.class, Codes.CODE, Codes.FAIL);
	}
}
